package com.wang.music.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.music.config.MinioPropertites;
import com.wang.music.config.MinioTemplate;
import com.wang.music.dao.SongMapper;
import com.wang.music.entity.Singer;
import com.wang.music.entity.Song;
import com.wang.music.service.SingerService;
import com.wang.music.service.SongService;
import com.wang.music.util.DateUtil;
import com.wang.music.util.FileUtils;
import com.wang.music.util.PageUtils;
import com.wang.music.util.ResMap;
import com.wang.music.vo.DicData;
import com.wang.music.vo.PageVO;
import com.wang.music.vo.SongVO_2;
import io.minio.MinioClient;
import io.minio.errors.InvalidEndpointException;
import io.minio.errors.InvalidPortException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 歌曲表 服务实现类
 * </p>
 *
 * @author zifan
 * @since 2021-03-05
 */
@Service
public class SongServiceImpl extends ServiceImpl<SongMapper, Song> implements SongService {

    @Autowired
    private MinioPropertites minioPropertites;

    @Autowired
    private SingerService singerService;


    /**
     * 获取一个MinioTemplate
     * @return
     */
    private MinioTemplate getMinioTemplate(){
        String url = minioPropertites.getUrl();
        MinioClient minioClient = null;
        try {
            minioClient = new MinioClient(url, minioPropertites.getAccessKey(), minioPropertites.getSecretKey());
        } catch (InvalidEndpointException e) {
            e.printStackTrace();
        } catch (InvalidPortException e) {
            e.printStackTrace();
        }
        MinioTemplate minioTemplate = new MinioTemplate(minioClient);
        return minioTemplate;
    }

    @Override
    public Map<String, Object> getSongs(String key, PageVO pageVO) {
        Map<String, Object> resMap = ResMap.OK();
        Page<Song> page = PageUtils.toMpPage(pageVO);
        QueryWrapper<Song> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(key)){
            wrapper.lambda().like(Song::getName,key);
        }
        this.page(page, wrapper);
        resMap.put("page",PageUtils.toPageVO(page));
        return resMap;
    }

    @Override
    public Map<String, Object> getSongList() {
        Map<String, Object> resMap = ResMap.OK();
        List<Singer> list = singerService.list();
        List<DicData> dicDataList = list.stream().map(singer -> {
            DicData dicData = new DicData();
            dicData.setLabel(singer.getName());
            dicData.setValue(singer.getId());
            return dicData;
        }).collect(Collectors.toList());
        resMap.put("list",dicDataList);
        return resMap;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> addSong(Song song) {
        Map<String, Object> resMap = ResMap.OK();
        Date now = new Date();
        song.setCreateTime(now);
        song.setUpdateTime(now);
        this.save(song);
        resMap.put("msg","新增成功");
        return resMap;
    }

    @Override
    public Map<String, Object> updateSong(Song song) {
        Map<String, Object> resMap = ResMap.OK();
        /**
         * 解决更新歌曲是的bug
         */
        if(StrUtil.isEmpty(song.getUrl())){
            QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Song::getId,song.getId());
            Song one = this.getOne(queryWrapper);
            song.setUrl(one.getUrl());
        }
        this.updateById(song);
        resMap.put("msg","更新成功！");
        return resMap;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> delSong(Song song) {
        Map<String, Object> resMap = ResMap.OK();
        //删除歌曲时判断，该歌曲是否又图片，有的话把图片也删了
        String pic = song.getPic();
        if(StrUtil.isNotEmpty(pic)){
            //获取图片名字
            String bucket = minioPropertites.getBucket();
            String s = StrUtil.subAfter(pic, bucket, true);
            MinioTemplate minioTemplate = getMinioTemplate();
            try {
                minioTemplate.removeObject(bucket,s);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        this.removeById(song.getId());
        resMap.put("msg","删除成功！");
        return resMap;
    }

    /**
     * 处理图片上传
     * @param pic
     * @return
     */
    @Override
    public Map<String, Object> uploadPic(MultipartFile pic) {
        HashMap<String, Object> resMap = new HashMap<>();
        String newName = FileUtils.upload("static/SongPic", pic);
        resMap.put("url","http://localhost:8888/SongPic/" + newName);
        resMap.put("name",newName);
        return resMap;
    }

    @Override
    public Map<String, Object> uploadSong(MultipartFile song) {
        HashMap<String, Object> resMap = new HashMap<>();
        MinioTemplate minioTemplate = new MinioTemplate(FileUtils.getMinioClient(minioPropertites));
        //对文件命做处理
        String filename = DateUtil.FormatDateForUpload(song.getOriginalFilename());
        String bucket = minioPropertites.getBucket();
        try {
            minioTemplate.putObject(bucket,filename,song.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //返回的url时页面上显示的url地址
        resMap.put("url",minioPropertites.getUrl() + "/" + bucket + filename);
        resMap.put("name",filename);



        return resMap;
    }

    @Override
    public Map<String, Object> uploadSongMinio(MultipartFile song) {
        Map<String, Object> resMap = ResMap.OK();
        try {
            String url = minioPropertites.getUrl();
            MinioClient minioClient = new MinioClient(url, minioPropertites.getAccessKey(), minioPropertites.getSecretKey());
            MinioTemplate minioTemplate = new MinioTemplate(minioClient);
            //对文件命做处理
            String filename = DateUtil.FormatDateForUpload(song.getOriginalFilename());
            String bucket = minioPropertites.getBucket();
            minioTemplate.putObject(bucket,filename,song.getInputStream());
            //返回的url时页面上显示的url地址
            resMap.put("url",url + "/" + bucket + filename);
            resMap.put("name",filename);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resMap;
    }

    /**
     * 这里大坑，数据库中存的是singerid，这里不直接转换就tm往前台传。我真是吐了这视频
     * 这人在前端对数据处理，我傻了。傻逼项目
     * @param songName
     * @return
     */
    @Override
    public List<SongVO_2> likeSongOfName(String songName) {
        QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(Song::getName,songName);
        List<Song> songs = this.list(queryWrapper);
        List<SongVO_2> songVO_2s = songs.stream().map(song -> {
            SongVO_2 songVO_2 = new SongVO_2();
            BeanUtils.copyProperties(song, songVO_2);
            QueryWrapper<Singer> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(Singer::getId, song.getSingerId());
            Singer one = singerService.getOne(wrapper);
            songVO_2.setSingerName(one.getName());
            return songVO_2;
        }).collect(Collectors.toList());
        return songVO_2s;
    }
}
